#include "php_gtk.h"

#if HAVE_PHP_GTK
#include <valhala.h>
#include "ext/gtk+/php_gtk+.h"
PHP_GTK_EXPORT_CE(valhalaobject_ce);
PHP_GTK_EXPORT_CE(valhala_ce);
	void phpg_valhala0_register_classes(void);


static PHP_METHOD(Valhala, hello2)
{
	gchar *php_retval, *cp_ret;
	gsize cp_len;
	zend_bool free_result;

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
		return;

    php_retval = valhala_hello2();
    if (php_retval) {
        cp_ret = phpg_from_utf8(php_retval, strlen(php_retval), &cp_len, &free_result TSRMLS_CC);
        if (cp_ret) {
            RETVAL_STRINGL((char *)cp_ret, cp_len, 1);
        } else {
            php_error(E_WARNING, "%s::%s(): could not convert return value from UTF-8", get_active_class_name(NULL TSRMLS_CC), get_active_function_name(TSRMLS_C));
        }
        g_free(php_retval);
        if (free_result)
            g_free(cp_ret);
    } else
        RETVAL_NULL();
}


static PHP_METHOD(Valhala, object_get_type)
{
	GType php_retval;

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
		return;

    php_retval = valhala_object_get_type();
    phpg_gtype_new(return_value, php_retval TSRMLS_CC);

}


static PHP_METHOD(Valhala, object_construct)
{
	GType object_type;
	zval *php_object_type = NULL;
	ValhalaObject* php_retval;

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "V", &php_object_type))
		return;
    if ((object_type = phpg_gtype_from_zval(php_object_type)) == 0) {
        return;
    }

    php_retval = valhala_object_construct(object_type);
    phpg_gobject_new(&return_value, (GObject *)php_retval TSRMLS_CC);
}


PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(arginfo_valhala_valhala_valhala_object_construct, 0)
    ZEND_ARG_OBJ_INFO(0, object_type, GType, 1)
ZEND_END_ARG_INFO();

static zend_function_entry valhala_methods[] = {
	PHP_ME(Valhala, hello2,       NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
	PHP_ME(Valhala, object_construct, arginfo_valhala_valhala_valhala_object_construct, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
	PHP_ME(Valhala, object_get_type, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
	{ NULL, NULL, NULL }
};

static PHP_METHOD(ValhalaObject, __construct)
{
    GObject *wrapped_obj;

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "")) {
        PHPG_THROW_CONSTRUCT_EXCEPTION(ValhalaObject);
    }


    wrapped_obj = (GObject *) g_object_newv(phpg_gtype_from_zval(this_ptr), 0, NULL);

    if (!wrapped_obj) {
        PHPG_THROW_CONSTRUCT_EXCEPTION(ValhalaObject);
    }

    phpg_gobject_set_wrapper(this_ptr, wrapped_obj TSRMLS_CC);
}


static PHP_METHOD(ValhalaObject, hello)
{
	gchar *php_retval, *cp_ret;
	gsize cp_len;
	zend_bool free_result;

    NOT_STATIC_METHOD();

	if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
		return;

    php_retval = valhala_object_hello(VALHALA_OBJECT(PHPG_GOBJECT(this_ptr)));
    if (php_retval) {
        cp_ret = phpg_from_utf8(php_retval, strlen(php_retval), &cp_len, &free_result TSRMLS_CC);
        if (cp_ret) {
            RETVAL_STRINGL((char *)cp_ret, cp_len, 1);
        } else {
            php_error(E_WARNING, "%s::%s(): could not convert return value from UTF-8", get_active_class_name(NULL TSRMLS_CC), get_active_function_name(TSRMLS_C));
        }
        g_free(php_retval);
        if (free_result)
            g_free(cp_ret);
    } else
        RETVAL_NULL();
}


static zend_function_entry valhalaobject_methods[] = {
	PHP_ME(ValhalaObject, __construct,          NULL, ZEND_ACC_PUBLIC)
	PHP_ME(ValhalaObject, hello,                NULL, ZEND_ACC_PUBLIC)
	{ NULL, NULL, NULL }
};

void phpg_valhala0_register_classes(void)
{
	TSRMLS_FETCH();

	valhala_ce = phpg_register_class("Valhala", valhala_methods, NULL, 0, NULL, NULL, 0 TSRMLS_CC);

	valhalaobject_ce = phpg_register_class("ValhalaObject", valhalaobject_methods, gobject_ce, 0, NULL, NULL, VALHALA_TYPE_OBJECT TSRMLS_CC);
}

void phpg_valhala_register_classes(void)
{
	TSRMLS_FETCH();
	phpg_valhala0_register_classes();
}

void phpg_valhala_register_constants(const char *strip_prefix)
{
    TSRMLS_FETCH();


    /* register gtype constants for all classes */

	phpg_register_int_constant(valhalaobject_ce, "gtype", sizeof("gtype")-1, VALHALA_TYPE_OBJECT);

}

#endif /* HAVE_PHP_GTK */
